-- 
-- Please see the readme.txt file included with this distribution for 
-- attribution and copyright information.
--

function getTargets(rActor, rEffect)
	local sTargetType = "targetct";
	local aTargets = {};
	
	if rActor then
		-- CHECK FOR SELF-TARGETING
		if (OptionsManager.isOption("SELF", "alt") and Input.isAltPressed()) or
				(rEffect and rEffect.sTargeting == "self") then
			if rActor.nodeCT then
				table.insert(aTargets, rActor.sCTNode);
			elseif rActor.sType == "pc" and rActor.nodeCreature then
				sTargetType = "targetpc";
				table.insert(aTargets, rActor.sCreatureNode);
			end

		-- CHECK FOR CLIENT OR HOST TARGETING
		elseif rActor.nodeCT then
			local nodeTargetList = rActor.nodeCT.getChild("targets");
			if nodeTargetList then
				local sTargetType = "client";
				if User.isHost() then
					sTargetType = "host";
				end

				for keyTarget, nodeTarget in pairs(nodeTargetList.getChildren()) do
					if NodeManager.get(nodeTarget, "type", "") == sTargetType then
						table.insert(aTargets, NodeManager.get(nodeTarget, "noderef", ""));
					end
				end
			end
		end
	end
	
	return sTargetType, aTargets;
end

function toggleTarget(sTargetType, sSourceNode, sTargetNode)
	local nodeSource = DB.findNode(sSourceNode);
	if nodeSource then
		if isTarget(sTargetType, nodeSource, sTargetNode) then
			removeTarget(sTargetType, nodeSource, sTargetNode);
		else
			addTarget(sTargetType, sSourceNode, sTargetNode);
		end
	end
end

function isTarget(sTargetType, nodeSource, sTargetNode)
	-- GET TARGET LIST
	local nodeTargetList = nodeSource.getChild("targets");
	if not nodeTargetList then
		return false;
	end
	
	-- CHECK TO SEE IF TARGET ALREADY ON LIST
	for keyTarget, nodeTarget in pairs(nodeTargetList.getChildren()) do
		if (NodeManager.get(nodeTarget, "noderef", "") == sTargetNode) and 
				(NodeManager.get(nodeTarget, "type", "") == sTargetType) then
			return true;
		end
	end
	
	-- NO MATCH FOUND
	return false;
end

function addTarget(sTargetType, sSourceNode, sTargetNode)
	-- GET SOURCE NODE
	local nodeSource = DB.findNode(sSourceNode);
	if not nodeSource then
		return;
	end

	-- GET TARGET LIST
	local nodeTargetList = nodeSource.getChild("targets");
	if not nodeTargetList then
		return;
	end
	
	-- CHECK TO SEE IF TARGET ALREADY ON LIST
	for keyTarget, nodeTarget in pairs(nodeTargetList.getChildren()) do
		if (NodeManager.get(nodeTarget, "noderef", "") == sTargetNode) and 
				(NodeManager.get(nodeTarget, "type", "") == sTargetType) then
			return;
		end
	end

	-- ADD THE NEW TARGET TO THE LIST
	local nodeNewTarget = nodeTargetList.createChild();
	if nodeNewTarget then
		NodeManager.set(nodeNewTarget, "type", "string", sTargetType);
		NodeManager.set(nodeNewTarget, "noderef", "string", sTargetNode);
	end
end

function addFactionTargets(sTargetType, nodeSource, sFaction, bNegated)
	-- VALIDATE
	if not nodeSource then
		return;
	end
	
	-- GET TRACKER
	local nodeTracker = DB.findNode("combattracker");
	if not nodeTracker then
		return;
	end

	-- ITERATE THROUGH TRACKER ENTRIES TO GET FACTION
	for keyEntry, nodeEntry in pairs(nodeTracker.getChildren()) do
		if bNegated then
			if NodeManager.get(nodeEntry, "friendfoe", "") ~= sFaction then
				addTarget(sTargetType, nodeSource.getNodeName(), nodeEntry.getNodeName());
			end
		else
			if NodeManager.get(nodeEntry, "friendfoe", "") == sFaction then
				addTarget(sTargetType, nodeSource.getNodeName(), nodeEntry.getNodeName());
			end
		end
	end
end

function removeTarget(sTargetType, nodeSource, sTargetNode)
	if User.isHost() then
		if nodeSource then
			local nodeTargetList = nodeSource.getChild("targets");
			if nodeTargetList then
				for keyTarget, nodeTarget in pairs(nodeTargetList.getChildren()) do
					if (NodeManager.get(nodeTarget, "type", "") == sTargetType) and
							(NodeManager.get(nodeTarget, "noderef", "") == sTargetNode) then
						nodeTarget.delete();
					end
				end
			end
		end
	else
		ChatManager.sendSpecialMessage(ChatManager.SPECIAL_MSGTYPE_REMOVECLIENTTARGET, { NodeManager.get(nodeSource, "name", ""), sTargetNode });
	end
end

function removeClientTarget(msguser, sSourceName, sTargetNode)
	local sSourceIdentity = nil;
	for k, v in ipairs(User.getAllActiveIdentities()) do
		if User.getIdentityLabel(v) == sSourceName then
			sSourceIdentity = v;
			break;
		end
	end
	if not sSourceIdentity then
		local msg = {font = "systemfont"};
		msg.text = "[WARNING] Unable to remove client target, attacker does not match any current client identity";
		ChatManager.deliverMessage(msg, msguser);
		return;
	end
	local wnd = Interface.findWindow("combattracker_window", "combattracker");
	if not wnd then
		local msg = {font = "systemfont"};
		msg.text = "[WARNING] Client targets can only be automatically removed when the host combat tracker is open";
		ChatManager.deliverMessage(msg, msguser);
		return;
	end
	for keyCTEntry, winCTEntry in pairs(wnd.list.getWindows()) do
		if winCTEntry.getDatabaseNode().getNodeName() == sTargetNode then
			local tokenCT = winCTEntry.token.getReference();
			if tokenCT then
				tokenCT.setTarget(false, sSourceIdentity);
			end
			break;
		end
	end
end

function removeTargetFromAllEntries(sTargetType, sTargetNode)
	local nodeTracker = DB.findNode("combattracker");
	if nodeTracker then
		for keyCTEntry, nodeCTEntry in pairs(nodeTracker.getChildren()) do
			removeTarget(sTargetType, nodeCTEntry, sTargetNode);
			
			local nodeEffects = nodeCTEntry.getChild("effects");
			if nodeEffects then
				for keyEffect, nodeEffect in pairs(nodeEffects.getChildren()) do
					local nodeTargets = nodeEffect.getChild("targets");
					if nodeTargets then
						local bHasTargets = false;
						if nodeTargets.getChildCount() > 0 then
							removeTarget(sTargetType, nodeEffect, sTargetNode);
					
							if nodeTargets.getChildCount() == 0 then
								EffectsManager.expireEffect(nodeCTEntry, nodeEffect, 0, true);
							end
						end
					end
				end
			end
		end
	end
end

function clearTargets(sTargetType, nodeSource)
	if nodeSource then
		local nodeTargetList = nodeSource.getChild("targets");
		if nodeTargetList then
			for keyTarget, nodeTarget in pairs(nodeTargetList.getChildren()) do
				if NodeManager.get(nodeTarget, "type", "") == sTargetType then
					nodeTarget.delete();
				end
			end
		end
	end
end
